using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using Mono.Cecil;

namespace ReferenceChecker
{
	public class Checker: IDisposable
	{
		List<ReferenceConnection> refernces;
		MD5 md5;

		public Checker()
		{
			md5 = MD5.Create();
			refernces = new List<ReferenceConnection>();
		}

		public void Execute(string directory)
		{
			foreach (var file in EnumerateFiles(directory))
			{
				try
				{
					var moduleDefinition = ModuleDefinition.ReadModule(file);

					ReferenceConnection referenceConnection = refernces.FirstOrDefault(connection => connection.FileName == Path.GetFileName(file));
					if (referenceConnection == null)
					{
						referenceConnection = new ReferenceConnection();
						refernces.Add(referenceConnection);
					}
					else
					{

					}
					foreach (var reference in moduleDefinition.AssemblyReferences)
					{
						Debug.WriteLine("\t" + reference.FullName);
					}
				}
				catch (BadImageFormatException)
				{
					Debug.WriteLine(string.Format("Skipped '{0}' because it is not a .net assembly", file));
				}
				catch (Exception exception)
				{
					Debug.WriteLine(string.Format("Could not process '{0}'. Exception: {1}", file, exception));
				}
			}
		}

		static IEnumerable<string> EnumerateFiles(string directory)
		{
			foreach (var file in Directory.EnumerateFiles(directory, "*.exe", SearchOption.AllDirectories))
			{
				yield return file;
			}
			foreach (var file in Directory.EnumerateFiles(directory, "*.dll", SearchOption.AllDirectories))
			{
				yield return file;
			}
		}

		public void Dispose()
		{
			if (md5 != null)
			{
				md5.Dispose();
			}
		}
	}
}